import matplotlib
import numpy as np
import matplotlib.pyplot as plt
# 设置 matplotlib 支持中文显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 'SimHei' 是一种常见的中文黑体字体
matplotlib.rcParams['axes.unicode_minus'] = False  # 正确显示负号

def ObjFun(ttt, id):
    n = np.array([100] * 8)
    mon = 0
    ma1 = np.array([
        [0.15, 2, 1],
        [0.15, 8, 1],
        [0.15, 12, 2],
        [0.15, 2, 1],
        [0.15, 8, 1],
        [0.15, 12, 2],
        [0.15, 8, 1],
        [0.15, 12, 2]
    ])
    ma2 = np.array([
        [0.15, 8, 4, 6],
        [0.15, 8, 4, 6],
        [0.15, 8, 4, 6]
    ])
    ma3 = np.array([0.15, 8, 6, 10])
    H = np.array([1000, 1000, 1000])
    D = 1000
    beta = 0

    for i in range(8):
        mon += ma1[i, 1] * ttt[i] * ma1[i, 2]

    for i in range(3):
        H[0] = min(n[i] * ma1[i, 0] * (1 - ttt[i]) + n[i] * (1 - ma1[i, 0]), H[0])
    for i in range(3, 6):
        H[1] = min(n[i] * ma1[i, 0] * (1 - ttt[i]) + n[i] * (1 - ma1[i, 0]), H[1])
    for i in range(6, 8):
        H[2] = min(n[i] * ma1[i, 0] * (1 - ttt[i]) + n[i] * (1 - ma1[i, 0]), H[2])

    for i in range(3):
        mon += (H[i] * ttt[i + 8] * ma2[i, 2] + H[i] * ma2[i, 1] + H[i] * ttt[i + 8] * ma2[i, 0] * ma2[i, 3] * ttt[11])

    for i in range(3):
        D = min(H[i] * ma2[i, 0] * (1 - ttt[i + 8]) + H[i] * (1 - ma2[i, 0]), D)

    z = np.concatenate((ma2[:, 0], ma3[:1]))
    for i in range(4):
        beta += z[i]
        for j in range(i, 4):
            beta -= z[i] * z[j]
            for k in range(j, 4):
                beta += z[i] * z[j] * z[k]
                for kk in range(k, 4):
                    beta -= z[i] * z[j] * z[k] * z[kk]

    mon += (D * ma3[1] + D * ttt[14] * ma3[2] + D * (1 - ttt[14]) * 40 * beta + D * beta * ttt[15] * 40)
    nn = D * beta * ttt[15]
    n = nn * n / 100

    return mon

def main():
    jingyushu = 20
    MAXGEN = 200
    weidu = 16
    ub = np.ones(weidu)
    lb = np.zeros(weidu)
    L_p = np.zeros(weidu)
    id = 5
    L_s = float('inf')
    PS = np.random.rand(jingyushu, weidu) * (ub - lb) + lb
    trace = np.zeros(MAXGEN)

    for kk in range(MAXGEN):
        for i in range(jingyushu):
            PS[i, PS[i, :] > ub] = ub[PS[i, :] > ub]
            PS[i, PS[i, :] < lb] = lb[PS[i, :] < lb]
            fitness = ObjFun(PS[i, :], id)
            if fitness < L_s:
                L_s = fitness
                L_p = PS[i, :].copy()
        a = 2 - kk * 2 / MAXGEN
        a2 = -1 - kk / MAXGEN
        for i in range(jingyushu):
            r1, r2 = np.random.rand(2)
            A = 2 * a * r1 - a
            C = 2 * r2
            b = 1
            l = (a2 - 1) * np.random.rand() + 1
            p = np.random.rand()
            pmutation = np.sin(np.pi / 3 + np.pi * kk / (6 * MAXGEN))
            for j in range(weidu):
                if p < pmutation:
                    if abs(A) >= 1:
                        rand_leader_index = np.random.randint(jingyushu)
                        X_r = PS[rand_leader_index, :]
                        D_x_r = abs(C * X_r[j] - PS[i, j])
                        PS[i, j] = X_r[j] - A * D_x_r
                    elif abs(A) < 1:
                        D_L = abs(C * L_p[j] - PS[i, j])
                        PS[i, j] = L_p[j] - A * D_L
                else:
                    distance_Leader = abs(L_p[j] - PS[i, j])
                    PS[i, j] = distance_Leader * np.exp(b * l) * np.cos(l * 2 * np.pi) + L_p[j]
        trace[kk] = L_s

    plt.plot(trace, linewidth=2)
    plt.xlabel('迭代次数')
    plt.ylabel('适应度值')
    plt.title('适应度曲线')
    plt.legend()
    plt.grid(True)
    plt.show()
    print(f"情况：{id}\n")
    print('答案:', L_p)
    print(f"代价：{L_s}")

if __name__ == "__main__":
    main()